package string;

/**
 * String字符串类:
 * 1.java会将所有使用字面量(直接量)形式创建的字符串对象缓存在常量池中，
 *   每当使用相同字面量形式创建字符串时，会重用对象以减少内存开销
 * 2.new String()创建时，一定会创建新对象
 * 3.String是不变对象，创建后内容不可改变，若改变则创建新对象
 * 4.若想比较字符串内容相同，需要使用equals()方法
 */
public class StringDemo {
    public static void main(String[] args) {
        /*
        String 字面量
        String s="" 直接量复制， 会重用常量池里面的东西
        String s=new String();  new 就会在堆中开辟空间，创建一个新对象 ,不会复用
         */
        String str = "123abc";// 第一次 直接量，会把 123abc 放入常量池
        System.out.println(str);
        String str2 = "123abc";// 后续使用 ，都会冲常量池中拿出来再给你赋值
        System.out.println(str2);
        String str3 = new String("123abc");// 完全在堆中创建一个新对象
        System.out.println(str3);
        String str4 = new String("123abc");// 完全在堆中创建一个新对象
        System.out.println(str4);//
        // 字符串中比较  是否相等，== 判断 地址值
        // 引用类型中，若两个对象地址值相同 那他们就是同一个对象
        System.out.println(str==str2);//true  复用 地址相同
        System.out.println(str==str3);// false new 创建新的对象，
        System.out.println(str3==str4);// false  new 创建新的对象，

        String s="123";
        String s1=s+"abc";
        System.out.println(str==s1);// ?  false 地址不同 。 变量的拼接，不会复用之前常量池中123abc

        String s2 ="123"+"abc";
        System.out.println(str==s2);//? true 字面量直接值，在拼接过程中会触发预计算特性，
        // 直接编译为String s2="123abc"，复用该对象池中123abc

        /**
         ==是比较值是否相等，对于引用类型而言，引用中保存的是地址，
         所以==比较的是地址，地址相同意味着两个引用指向了同一个对象，

         对于字符串而言，实际应用中我们通常希望比较的是两个字符串的内容是否相同，
         因此一般都是通过equals()来比较字符串内容是否相同的

         * 字符串的比较 使用 equals（） 比较的是内容是否相等，内容相同即为true
         */

        String s3="123abc";
        String s4=new String("123abc");
        System.out.println(s3==s4);// false  地址不同
        System.out.println(s3.equals(s4));// true  equals() 比较的是 字面量值，相同代表一样




    }
}
